#include <QApplication>
#include <QMainWindow>
#include <QTextEdit>
#include <QPushButton>
#include <QVBoxLayout>
#include <QHBoxLayout>
#include <QLabel>
#include <QSpinBox>
#include <QCheckBox>
#include <QRandomGenerator>
#include <QTextStream>
#include <QFile>
#include <QMessageBox>
#include <QFileDialog>
#include <QHash>
#include <QRegularExpression>

class PoetryGenerator : public QMainWindow {
    Q_OBJECT
public:
    PoetryGenerator(QWidget *parent = nullptr) : QMainWindow(parent) {
        setupUI();
        loadDefaultWordBank();
    }

    void showHelpInfo() {
        QString helpText =
            "词库文件格式要求：\n\n"
            "1. 使用UTF-8编码的文本文件\n"
            "2. 包含以下必需章节：\n"
            "   [nouns]      - 名词列表\n"
            "   [verbs]      - 动词列表\n"
            "   [adjectives] - 形容词列表\n"
            "   [adverbs]    - 副词列表\n\n"
            "3. 可选章节：\n"
            "   [rhymes]     - 押韵模式韵脚\n\n"
            "4. 每行一个词语，示例：\n"
            "--------------------------------\n"
            "[nouns]\n"
            "水滴[i]\n"
            "二向箔[o]\n"
            "\n"
            "[verbs]\n"
            "降维[ei]\n"
            "广播[o]\n"
            "注意：章节间一定要有空格";

        QMessageBox::information(this,
                                 "导入说明",
                                 helpText,
                                 QMessageBox::Ok);
    }

private:
    QHash<QString, QString> rhymeMap = {
        {"a", "啊阿吖"},
        {"an", "安案暗"},
        {"ang", "昂盎"},
        {"ao", "奥熬傲"},
        // 继续添加其他韵母...
    };
    QHash<QString, QString> nounRhymes;  // 名词韵脚
    QHash<QString, QString> verbRhymes;  // 动词韵脚
    QHash<QString, QString> adjRhymes;   // 形容词韵脚
    QHash<QString, QString> advRhymes;   // 副词韵脚

    void setupUI() {
        QPushButton *importBtn = new QPushButton("导入词库");  // 界面组件
        QPushButton *helpBtn = new QPushButton("导入前须知");  // 界面组件
        connect(importBtn, &QPushButton::clicked, this, &PoetryGenerator::importWordBank);
        QWidget *centralWidget = new QWidget(this);
        QVBoxLayout *mainLayout = new QVBoxLayout(centralWidget);

        QHBoxLayout *controlLayout = new QHBoxLayout();
        QLabel *label = new QLabel("诗歌行数:");
        spinBox = new QSpinBox;
        spinBox->setRange(4, 100);
        spinBox->setValue(8);

        rhymeCheck = new QCheckBox("启用押韵");
        generateBtn = new QPushButton("生成诗歌");

        controlLayout->addWidget(label);
        controlLayout->addWidget(spinBox);
        controlLayout->addWidget(rhymeCheck);
        controlLayout->addWidget(generateBtn);
        controlLayout->addWidget(importBtn);
        controlLayout->addWidget(helpBtn);

        outputArea = new QTextEdit;
        outputArea->setReadOnly(true);

        mainLayout->addLayout(controlLayout);
        mainLayout->addWidget(outputArea);
        centralWidget->setLayout(mainLayout);
        setCentralWidget(centralWidget);

        connect(generateBtn, &QPushButton::clicked, this, &PoetryGenerator::generatePoetry);

        connect(helpBtn, &QPushButton::clicked, this, &PoetryGenerator::showHelpInfo);
    }

    void loadDefaultWordBank() {
        QStringList baseNouns = {"春风[ing]", "夏雨[yu]", "秋叶[ie]", "冬雪[ue]",
                                 "山川[an]", "河流[iu]", "星辰[xing]", "岁月[sui]",
                                 "天空[kong]", "大地[di]", "海洋[yang]", "森林[lin]",
                                 "城市[shi]", "乡村[cun]", "梦想[xiang]", "远方[yang]",
                                 "沙漠[mo]", "草原[pu]", "雪山[xue]", "湖泊[bo]"};
        QStringList baseVerbs = {"轻拂[fu]", "洒落[uo]", "飘零[ing]", "覆盖[gai]",
                                 "流淌[tang]", "闪烁[sho]", "流逝[si]", "绽放[fang]",
                                 "吟唱[ang]", "舞动[dong]", "飞翔[xiang]", "探索[suo]",
                                 "奔跑[pao]", "跳跃[yue]", "攀登[deng]", "漂浮[fu]"};
        QStringList baseAdj = {"温柔的[rou]", "炽热的[chi]", "金黄的[jin]", "洁白的[bai]",
                               "壮丽的[li]", "深邃的[sui]", "悠远的[yu]", "热情的[qing]",
                               "宁静的[jing]", "神秘的[shen]", "广阔的[guang]", "深远的[yuan]",
                               "淡雅的[ya]", "明亮的[ming]", "幽暗的[an]", "粘稠的[niao]"};
        QStringList baseAdv = {"轻柔地[qing]", "悄然地[tan]", "深情地[qing]", "缓缓地[huan]",
                               "静静的[jing]", "无尽地[jin]", "迅速地[su]", "默默地[mo]",
                               "欢快地[kuai]", "静静地[jing]", "轻轻的[qing]", "徐徐地[xu]",
                               "晃晃地[huang]", "深深地[shen]", "远远地[yuan]", "高高地[gao]"};

        parseRhymeWords(baseNouns, nounRhymes);
        parseRhymeWords(baseVerbs, verbRhymes);
        parseRhymeWords(baseAdj, adjRhymes);
        parseRhymeWords(baseAdv, advRhymes);

        nouns = nounRhymes.keys();
        verbs = verbRhymes.keys();
        adjectives = adjRhymes.keys();
        adverbs = advRhymes.keys();
    }

    void parseRhymeWords(const QStringList &words, QHash<QString, QString> &target) {
        QRegularExpression rhymePattern(R"((.+?)\[(\w+)\])");
        foreach (const QString &word, words) {
            QRegularExpressionMatch match = rhymePattern.match(word);
            if (match.hasMatch()) {
                target[match.captured(1)] = match.captured(2);
            } else {
                target[word] = "default";
            }
        }
    }

private slots:
    void generatePoetry() {
        outputArea->clear();
        QStringList poem;
        QString currentRhyme;

        if (rhymeCheck->isChecked()) {
            if (!nounRhymes.isEmpty()) {
                QStringList rhymes = nounRhymes.values();
                QStringList uniqueRhymes;
                for (const QString &rhyme : rhymes) {
                    if (!uniqueRhymes.contains(rhyme)) {
                        uniqueRhymes << rhyme;
                    }
                }
                if (!uniqueRhymes.isEmpty()) {
                    currentRhyme = uniqueRhymes[QRandomGenerator::global()->bounded(uniqueRhymes.size())];
                }
            } else if (!verbRhymes.isEmpty()) {
                QStringList rhymes = verbRhymes.values();
                QStringList uniqueRhymes;
                for (const QString &rhyme : rhymes) {
                    if (!uniqueRhymes.contains(rhyme)) {
                        uniqueRhymes << rhyme;
                    }
                }
                if (!uniqueRhymes.isEmpty()) {
                    currentRhyme = uniqueRhymes[QRandomGenerator::global()->bounded(uniqueRhymes.size())];
                }
            }else if (!adjRhymes.isEmpty()) {
                QStringList rhymes = adjRhymes.values();
                QStringList uniqueRhymes;
                for (const QString &rhyme : rhymes) {
                    if (!uniqueRhymes.contains(rhyme)) {
                        uniqueRhymes << rhyme;
                    }
                }
                if (!uniqueRhymes.isEmpty()) {
                    currentRhyme = uniqueRhymes[QRandomGenerator::global()->bounded(uniqueRhymes.size())];
                }
            }else if (!advRhymes.isEmpty()) {
                QStringList rhymes = advRhymes.values();
                QStringList uniqueRhymes;
                for (const QString &rhyme : rhymes) {
                    if (!uniqueRhymes.contains(rhyme)) {
                        uniqueRhymes << rhyme;
                    }
                }
                if (!uniqueRhymes.isEmpty()) {
                    currentRhyme = uniqueRhymes[QRandomGenerator::global()->bounded(uniqueRhymes.size())];
                }
            }
        }

        for (int i = 0; i < spinBox->value(); ++i) {
            QString line = generateLine(i, currentRhyme);
            poem << line;
        }

        outputArea->setText(poem.join("\n"));
    }

    void importWordBank() {
        QString fileName = QFileDialog::getOpenFileName(
            this, "选择词库文件", "", "词库文件 (*.txt)");

        if (fileName.isEmpty()) return;

        QFile file(fileName);
        if (!file.open(QIODevice::ReadOnly | QIODevice::Text)) {
            showError("无法打开文件");
            return;
        }

        QTextStream in(&file);
        QRegularExpression rhymePattern(R"((.+?)\[(\w+)\])");

        nounRhymes.clear();
        verbRhymes.clear();
        adjRhymes.clear();
        advRhymes.clear();

        QString currentSection;
        while (!in.atEnd()) {
            QString line = in.readLine().trimmed();
            if (line.isEmpty() || line.startsWith("#")) continue;

            if (line.startsWith("[")) {
                currentSection = line.toLower();
                continue;
            }

            QRegularExpressionMatch match = rhymePattern.match(line);
            if (match.hasMatch()) {
                QString word = match.captured(1);
                QString rhyme = match.captured(2);

                if (currentSection == "[nouns]") {
                    nouns << word;
                    nounRhymes[word] = rhyme;
                } else if (currentSection == "[verbs]") {
                    verbs << word;
                    verbRhymes[word] = rhyme;
                } else if (currentSection == "[adjectives]") {
                    adjectives << word;
                    adjRhymes[word] = rhyme;
                } else if (currentSection == "[adverbs]") {
                    adverbs << word;
                    advRhymes[word] = rhyme;
                }
            } else {
                if (currentSection == "[nouns]") {
                    nouns << line;
                    nounRhymes[line] = "default";
                } else if (currentSection == "[verbs]") {
                    verbs << line;
                    verbRhymes[line] = "default";
                } else if (currentSection == "[adjectives]") {
                    adjectives << line;
                    adjRhymes[line] = "default";
                } else if (currentSection == "[adverbs]") {
                    adverbs << line;
                    advRhymes[line] = "default";
                }
            }
        }
        file.close();

        QMessageBox::information(this, "成功",
                                 QString("词库加载成功！\n名词:%1 动词:%2\n形容词:%3 副词:%4")
                                     .arg(nouns.size()).arg(verbs.size())
                                     .arg(adjectives.size()).arg(adverbs.size()));
    }

    void showError(const QString &message) {
        QMessageBox::warning(this, "格式错误",
                             QString("词库导入失败：%1\n请确保文件格式符合要求：\n"
                                     "1. 使用UTF-8编码\n"
                                     "2. 包含[nouns]、[verbs]等章节\n"
                                     "3. 每行一个词语").arg(message));
    }

private:
    QString generateLine(int lineNum, QString rhyme) {
        QVector<QString> patterns = {
            "[形容词][名词][动词][名词]",
            "[副词][动词][名词]",
            "[名词]在[动词]",
            "[形容词][名词]的[名词]"
        };

        QString pattern = patterns[QRandomGenerator::global()->bounded(patterns.size())];
        QString line;

        // 记录已经使用的词汇，避免在同一句中重复使用
        QSet<QString> usedWords;

        line = pattern;
        while (line.contains("[形容词]")) {
            QString adj = randomWord(adjectives, usedWords);
            if (!adj.isEmpty()) {
                line.replace("[形容词]", adj, Qt::CaseSensitive);
                usedWords.insert(adj);
            } else {
                line.remove("[形容词]");
            }
        }
        while (line.contains("[名词]")) {
            QString noun = randomWord(nouns, usedWords);
            if (!noun.isEmpty()) {
                line.replace("[名词]", noun, Qt::CaseSensitive);
                usedWords.insert(noun);
            } else {
                line.remove("[名词]");
            }
        }
        while (line.contains("[动词]")) {
            QString verb = randomWord(verbs, usedWords);
            if (!verb.isEmpty()) {
                line.replace("[动词]", verb, Qt::CaseSensitive);
                usedWords.insert(verb);
            } else {
                line.remove("[动词]");
            }
        }
        while (line.contains("[副词]")) {
            QString adv = randomWord(adverbs, usedWords);
            if (!adv.isEmpty()) {
                line.replace("[副词]", adv, Qt::CaseSensitive);
                usedWords.insert(adv);
            } else {
                line.remove("[副词]");
            }
        }

        if (!rhyme.isEmpty() && (lineNum + 1) % 4 == 0) {
            line = forceRhyme(line, rhyme);
        }

        return line;
    }

    QString randomWord(const QStringList &words, QSet<QString> &usedWords) {
        if (words.isEmpty()) {
            return QString();
        }

        QString word;
        QRandomGenerator *generator = QRandomGenerator::global();
        int index = generator->bounded(words.size());
        word = words[index];

        // 如果词汇已经使用过，则尝试重新选择
        while (usedWords.contains(word) && words.size() > 1) {
            index = generator->bounded(words.size());
            word = words[index];
        }

        return word;
    }

    QString forceRhyme(QString line, const QString &targetRhyme) {
        QRegularExpression re("\\[(.*?)\\]");
        QRegularExpressionMatchIterator i = re.globalMatch(line);

        QStringList replacePoints;
        while (i.hasNext()) {
            QRegularExpressionMatch match = i.next();
            replacePoints << match.captured(1);
        }

        if (!replacePoints.isEmpty()) {
            QString lastWord = replacePoints.last();
            QStringList candidates;

            for (const QString &word : nouns) {
                if (nounRhymes.value(word) == targetRhyme) {
                    candidates << word;
                }
            }

            if (!candidates.isEmpty()) {
                QString newWord = candidates[QRandomGenerator::global()->bounded(candidates.size())];
                if (!newWord.isEmpty()) {
                    line.replace("[" + lastWord + "]", newWord, Qt::CaseSensitive);
                }
            }
        }
        return line;
    }

    QSpinBox *spinBox;
    QCheckBox *rhymeCheck;
    QPushButton *generateBtn;
    QTextEdit *outputArea;

    QStringList nouns;
    QStringList verbs;
    QStringList adjectives;
    QStringList adverbs;
    QStringList rhymes;
};

int main(int argc, char *argv[]) {
    QApplication a(argc, argv);
    PoetryGenerator w;
    w.resize(600, 400);
    w.show();
    return a.exec();
}
